package main

import (
	"bufio"
	"fmt"
	"os"
	"time"
)

func tryDefer() {
	//defer 函数退出前操作(先进后出的栈)
	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
		if i == 4 {
			panic("printed too many err")
		}
	}
}

//斐波那契数列(初始值1, 1; 后续的值为前两个值的和)
// 1, 1, 2, 3, 5, 8, 13, ...
func Fibonacci() func() int {
	//a,b 用于第三个数进行累加
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return a
	}
}

func writeFile(filename string) {
	file, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	//bufio 先写内存
	writer := bufio.NewWriter(file)
	//再一次性刷到磁盘
	defer writer.Flush()
	fib := Fibonacci()
	for i := 0; i < 20; i++ {
		fmt.Fprintln(writer, fib())
	}
}

func writeFileErr(filename string) {
	//文件名;  执行方式执行/创建/写;  0666是linux文件权限
	//删除 os.O_TRUNC 写权限
	file, err := os.OpenFile(filename, os.O_EXCL|os.O_CREATE, 0666)
	if err != nil {
		if pathError, ok := err.(*os.PathError); ok {
			fmt.Printf("op=%s, path=%s, err=%s \n", pathError.Op,
				pathError.Path,
				pathError.Err)
		} else {
			// 非 os.PathError 直接打印
			panic(err)
		}
		//panic(err)
		//errors.New("this is a udf error")
		fmt.Println("缺失 os.O_TRUNC 权限, 无法修改已存在的文件 ", err.Error())
		panic(NewUdfErr("udf error"))
		return
	}
	defer file.Close()
	//bufio 先写内存
	writer := bufio.NewWriter(file)
	//再一次性刷到磁盘
	defer writer.Flush()
	fib := Fibonacci()
	for i := 0; i < 20; i++ {
		fmt.Fprintln(writer, fib())
	}
}

func main() {

	//timeTest()

	//创建了需要close的对象,那么就可以使用defer
	//writeFileErr("fib.txt")

	//先进后出(栈)
	tryDefer()

}

type UdfError struct {
	msg string
}

func NewUdfErr(udfMsg string) UdfError {
	return UdfError{
		msg: udfMsg,
	}
}

//udf error
func (this UdfError) Error() string {
	return this.msg
}

const (
	Datelayout = "2006-01-02"
	Timelayout = "2006-01-02 15:04:05"
)

//ParseDate 获取时间
func ParseDate(timeStr string) (time.Time, error) {
	return time.Parse(Timelayout, timeStr)
}

func DefaultCreateTime() time.Time {
	return time.Date(1970, 1, 2, 8, 0, 0, 0, time.Local)
}

func timeTest() {
	udfTime, _ := ParseDate("2021-12-17 00:00:00")
	if udfTime.Sub(DefaultCreateTime()) > 0 {
		fmt.Println(udfTime)
	} else {
		fmt.Println("error time")
	}
}
